#include <pic18f6722.h>

#define uint unsigned int
#define uchar unsigned char
#define uchar unsigned char
#define uint unsigned int

#define scl    RA0
#define sda    RA1
#define scl_OUTPUT   TRISA = TRISA & 0xFE
#define sda_OUTPUT   TRISA = TRISA & 0xFD
#define sda_INPUT    TRISA = TRISA | 0x02

void PIC_IIC_Delayus();
void PIC_IIC_Delayms(unsigned int ms);
void PIC_Write_Char_To_EEPROM(uint Addr, uchar Data);
uchar PIC_Read_Char_From_EEPROM(uint Addr);
void PIC_IIC_Initialize();
void PIC_IIC_Start();
void PIC_IIC_Stop();
void PIC_IIC_SendByte(unsigned char byteData);
unsigned char PIC_IIC_ReadByte();
unsigned char PIC_IIC_CheckACK();
void PIC_IIC_SendACK(unsigned char b_ACK);

//********************************************************************
/* write a byte to EEPROM
 * input: unint Addr; EEPROM address
 *        uchar Data: data to be writed to EEPROM
 * return: void
 * author: Guichuan.He
 * date: 2016-9-23
*/
//**********************************************************************
void PIC_Write_Char_To_EEPROM(uint Addr, uchar Data)
{ 
    EEADRH  = (Addr>>8) & 0x03;
    EEADR   = Addr & 0xFF;
    
    EEDATA  = Data & 0xFF;
  
    EECON1  = EECON1 & 0x7F;    // EPGD = 0; CFGS = 0;  
    EECON1 =  EECON1 & 0xBF;
    
    INTCON  = INTCON & 0x7F;    //GIE = 0;
    
    EECON1  = EECON1 | 0x04;    //WREN = 1;
    
    //INTCON  = INTCON & 0x7F;    //GIE = 0;
    
    EECON2  = 0x55;
    EECON2  = 0xAA;
   
    EECON1 = EECON1 | 0x02;
    INTCON = INTCON | 0x80;
   
  //  while( (EECON1 & 0x02) == 1);
   
 //   while(1)
    {
        if ( EEIF == 1 )
        {
            EEIF = 0;
   //         break;
        }
    }

    EECON1 = EECON1 & 0xFB;    //WREN = 0;
}

//********************************************************************
/* Read a byte from EEPROM
 * input: unint Addr; EEPROM address
 * return: uchar: data read from EEPROM
 * author: Guichuan.He
 * date: 2016-9-26
*/
//**********************************************************************
uchar PIC_Read_Char_From_EEPROM(uint Addr)
{
    uchar ReadData;
    
    EEADRH  = (Addr>>8) & 0x03;
    EEADR   = Addr & 0xFF;
    EECON1  = EECON1 & 0x3F;    // EPGD = 0; CFGS = 0; 
    EECON1  = EECON1 | 0x01;
    
    ReadData = EEDATA;
    
    return ReadData; 
}

//********************************************************************
/* IIC pin Initialize
 * input: void
 * return: scl & sda are all high level.
 * author: Guichuan.He
 * date: 2016-9-26
*/
//********************************************************************** 
void PIC_IIC_Initialize() 
{   
    scl_OUTPUT;
    sda_OUTPUT;
    
    scl=1;   
    sda=1;   
    PIC_IIC_Delayus();   
}

//********************************************************************
/* IIC Start signal 
 * input: void
 * return: void
 * author: Guichuan.He
 * date: 2016-9-26
*/
//********************************************************************** 
void PIC_IIC_Start()  
{   
    sda_OUTPUT;
    
    sda=1;   
    scl=1;   
    PIC_IIC_Delayus();      
    PIC_IIC_Delayus();           
    sda=0;         
    PIC_IIC_Delayus();      
}   

//********************************************************************
/* IIC Stop signal 
 * input: void
 * return: void
 * author: Guichuan.He
 * date: 2016-9-26
*/
//********************************************************************** 
void PIC_IIC_Stop()
{   
   sda_OUTPUT;
    
    sda=0;
	PIC_IIC_Delayus();    
    scl=1;   
    PIC_IIC_Delayus();     
    sda=1;         
    PIC_IIC_Delayus();       
}   

//********************************************************************
/* IIC Send a byte 
 * input: unsigned char byteData
 * return: void
 * author: Guichuan.He
 * date: 2016-9-26
*/
//********************************************************************** 
void PIC_IIC_SendByte(unsigned char byteData) 
{ 
    unsigned char i;   
    unsigned char temp;
	unsigned char temp_and = 0x80;
    
    sda_OUTPUT;
     
    for(i=0;i<8;i++)   
    {   
        scl=0;          
        PIC_IIC_Delayus();;            
        
		temp = byteData & temp_and;
		if(temp == 0x00)
		   sda = 0;         
        else
		  sda = 1;
		 
		PIC_IIC_Delayus();   
        scl=1;           
        PIC_IIC_Delayus();
	    temp_and = temp_and >>1;           
    }   
  
    scl=0;              
    PIC_IIC_Delayus();                   
    sda=1;             
    PIC_IIC_Delayus();   
}   

//********************************************************************
/* IIC Read a byte 
 * input:  void
 * return: unsigned char byteData
 * author: Guichuan.He
 * date: 2016-9-26
*/
//********************************************************************** 
unsigned char PIC_IIC_ReadByte() 
{   
    unsigned char i,temp;  
    
    sda_OUTPUT;
     
    scl=0;             
    PIC_IIC_Delayus();   
    sda=1;             
    PIC_IIC_Delayus();   
  
    sda_INPUT; 
    
    for(i=0;i<8;i++)   
    {   
        scl=1;          
        PIC_IIC_Delayus();     
                            
		if(1 == sda)
         temp=(temp<<1) | 0x01;
		  
        else
		    temp=(temp<<1);
		   
		scl=0;   
        PIC_IIC_Delayus();         
    }   
    return temp;   
}   

//********************************************************************
/* IIC ACK check
 * input:  void
 * return: unsigned char, 0 -error , 1-ok
 * author: Guichuan.He
 * date: 2016-9-26
*/
//********************************************************************** 
unsigned char PIC_IIC_CheckACK()     
{   
    unsigned int errCounts= 50;
    sda_INPUT;
    
    scl=1;   
    PIC_IIC_Delayus();   
 
    while(sda)   
    {   
        if(0==errCounts)   
        {   
            scl=0;        
            PIC_IIC_Delayus(); 

            return 0; 
        }  
        PIC_IIC_Delayus(); 
        errCounts--;   
    }   

    scl=0;            
    PIC_IIC_Delayus();   
    return 1;      
}   
   
//********************************************************************
/* IIC Send ACK
 * input:  unsigned char b_ACK, BIT
 * return: void
 * author: Guichuan.He
 * date: 2016-9-27
*/
//********************************************************************** 
void PIC_IIC_SendACK(unsigned char b_ACK)    
{   
    sda_OUTPUT;
    
    scl=0;           
    PIC_IIC_Delayus();   
  
    if(b_ACK)       //ACK   
    {   
        sda=0;   
    }   
    else               //unACK   
    {   
        sda=1;   
    }   
  
    PIC_IIC_Delayus();   
    scl=1;   
    PIC_IIC_Delayus();      
    scl=0;                   
    PIC_IIC_Delayus();;   
}   
 
//*********************************************************************
/* PIC IIC Delay ms
 * author: Guichuan.He
 * date: 2016-9-26
*/
//**********************************************************************
void PIC_IIC_Delayms(unsigned int ms)  
{   
    unsigned int i,j;   
    for(i=ms;i>0;i--)   
    {   
        for(j=226;j>0;j--);  
    }   
} 

//*********************************************************************
/* PIC IIC Delay us
 * author: Guichuan.He
 * date: 2016-9-26
*/
//**********************************************************************
void PIC_IIC_Delayus()  
{   
    unsigned int j;
//	for(j=200;j>0;j--)   
    for(j=10;j>0;j--)  
    {}   
}


   